﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using DNA.OpenAPI.Atom;
using DNA.OpenAPI.OpenSearch;
using System.Web;

namespace DNA.Mvc.Searching.Providers
{
    public class WebPageSearchProvider : OpenSearchProvider
    {
        private IDataContext dbContext;
        public WebPageSearchProvider(IDataContext dataContext)
        {
            this.dbContext = dataContext;
        }

        public override string Name
        {
            get
            {
                return "sites";
            }
            set
            {
                base.Name = value;
            }
        }

        public override string Title
        {
            get { return "Sites"; }
        }

        public override bool SupportSuggestion
        {
            get
            {
                return true;
            }
        }

        public override IEnumerable<OpenSearchSuggestion> Suggest(string searchTerms, int count)
        {
            var comparer = new OpenSearchSuggestionComparer();
            return dbContext.WebPages.Filter(p => p.Title.StartsWith(searchTerms))
                 .OrderBy(p => p.Title)
                 .Select(p => new OpenSearchSuggestion()
                         {
                             SearchTerms = p.Title,
                             Description = p.Description
                         })
                         .ToList()
                         .Distinct(comparer)
                         .Take(count);
        }

        public override IEnumerable<AtomEntry> GetAtomResult(string searchTerms, int pageIndex, int pageSize, out int totalRecords)
        {
            //using (var db = DBMan.Instance())
            //{
            var searchPages = new List<WebPage>();
            var widgets = dbContext.Widgets.Filter(w => w.Action.Equals("SimpleHtml", StringComparison.OrdinalIgnoreCase) || w.Action.Equals("Wiki", StringComparison.OrdinalIgnoreCase));

            foreach (var widget in widgets)
            {
                var udata = widget.ReadUserPreferences();
                foreach (var key in udata.Keys)
                {
                    var v = udata[key];
                    if ((v != null) && (v.ToString().Contains(searchTerms)))
                    {
                        var _page = widget.WebPage;
                        if (_page.AllowAnonymous)
                            searchPages.Add(_page);
                    }
                }
            }

            var pages = dbContext.WebPages.Filter(p => ((p.Title.Contains(searchTerms) || p.Description.Contains(searchTerms)) && p.AllowAnonymous == true)).ToList();

            if (pages.Count() > 0) searchPages.AddRange(pages);


            var skip = (pageIndex - 1) * pageSize;
            if (skip == 0) skip = 0;


            var distinctResultSet = new List<WebPage>();
            var ids = searchPages.Select(p => p.ID).Distinct().ToArray();
            if (searchPages.Count() > 0)
            {
                foreach (var id in ids)
                    distinctResultSet.Add(searchPages.First(p => p.ID == id));
            }
            totalRecords = distinctResultSet.Count();
            var resultPages = distinctResultSet.OrderByDescending(p => p.ID).Skip(skip).Take(pageSize);
            var entries = new List<AtomEntry>();

            foreach (var page in resultPages)
            {
                var permaLink = UrlResolver.Resolve(new HttpContextWrapper(HttpContext.Current), page);

                //.PermalinkUrl.ToString();

                var builder = new AtomEntryBuilder(page.Title, permaLink);
                if (!string.IsNullOrEmpty(page.Description))
                    builder.SetSummary(page.Description);
                builder.SetPublished(page.LastModified);
                builder.SetContent(page.Description, src: permaLink);
                builder.SetAuthor(page.Owner, email: System.Web.Security.Membership.GetUser(page.Owner).Email);
                builder.SetLastUpdated(page.LastModified);
                builder.AddLink(permaLink);
                entries.Add(builder.Entry);
            }
            return entries;
            //}
        }

        public override IEnumerable<OpenAPI.Rss.RssItem> GetRssResult(string searchTerms, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }
    }
}